package ml;

import java.util.ArrayList;

import util.DataUtil;

public class TrainSampleMaker {
	private ArrayList<SampleData> m_train_samples = new ArrayList<SampleData>();
	private ArrayList<Boolean> m_train_labels = new ArrayList<Boolean>();
	private ArrayList<SampleData> m_test_samples_front = new ArrayList<SampleData>();
	private ArrayList<Boolean> m_test_labels_front = new ArrayList<Boolean>();
	private ArrayList<SampleData> m_test_samples_end = new ArrayList<SampleData>();
	private ArrayList<Boolean> m_test_labels_end = new ArrayList<Boolean>();

	public TrainSampleMaker(ArrayList<SampleData> all_samples, ArrayList<Boolean> all_labels,
					double train_samples_rate, boolean is_train, int train_begin_sample,
					int max_train_samples) {
		assert (train_begin_sample < all_samples.size());

		int train_samples = max_train_samples;
		if ((train_begin_sample + train_samples > all_samples.size()) || (train_samples < 0)) {
			train_samples = all_samples.size() - train_begin_sample;
		}
		int train_sample_num = (int) Math.ceil(train_samples_rate * train_samples);
		if (train_sample_num > train_samples) {
			train_sample_num = train_samples;
		}
		assert (train_sample_num > 0);
		assert (train_sample_num <= all_samples.size());

		if (is_train) {
			ArrayList<Integer> m_rands = DataUtil.GetMRandsFromN(train_sample_num, train_samples);

			for (int i : m_rands) {
				m_train_samples.add(all_samples.get(i + train_begin_sample));
				m_train_labels.add(all_labels.get(i + train_begin_sample));
			}
		}

		/*
		 * If max_trains_samples < 0, it means I want to use the whole dataset
		 * to train and test, else means I want to use up to max_trains_samples
		 * to train and the others to test.
		 */
		if ((!is_train) && (max_train_samples < 0)) {
			m_test_samples_front = all_samples;
			m_test_labels_front = all_labels;
			m_test_samples_end.clear();
			m_test_labels_end.clear();
		} else {
			for (int i = 0; i < train_begin_sample; ++i) {
				m_test_samples_front.add(all_samples.get(i));
				m_test_labels_front.add(all_labels.get(i));
			}
			for (int i = train_begin_sample + train_samples; i < all_samples.size(); ++i) {
				m_test_samples_end.add(all_samples.get(i));
				m_test_labels_end.add(all_labels.get(i));
			}
		}

		if (m_test_samples_front.size() > 0) {
			System.out.println("Front Test Samples: from\t"
							+ m_test_samples_front.get(0).get_date() + "\tto\t"
							+ m_test_samples_front.get(m_test_samples_front.size() - 1).get_date());
		}
		if (m_test_samples_end.size() > 0) {
			System.out.println("End Test Samples: from\t" + m_test_samples_end.get(0).get_date()
							+ "\tto\t"
							+ m_test_samples_end.get(m_test_samples_end.size() - 1).get_date());
		}
	}

	public ArrayList<SampleData> get_train_samples() {
		return m_train_samples;
	}

	public ArrayList<Boolean> get_train_labels() {
		return m_train_labels;
	}

	public ArrayList<SampleData> get_test_samples_front() {
		return m_test_samples_front;
	}

	public ArrayList<Boolean> get_test_labels_front() {
		return m_test_labels_front;
	}

	public ArrayList<SampleData> get_test_samples_end() {
		return m_test_samples_end;
	}

	public ArrayList<Boolean> get_test_labels_end() {
		return m_test_labels_end;
	}
}
